package com.yonyou.pmclouds.project.processor;

import com.yonyou.pmclouds.basecom.billstatus.BillStatusConst;
import com.yonyou.pmclouds.basecom.bp.processor.MultiProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.SingleProcessor;
import com.yonyou.pmclouds.basecom.entity.SuperVO;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.util.BeanHelper;
import com.yonyou.pmclouds.basecom.util.CommonFieldConst;
import com.yonyou.pmclouds.project.entity.ProjectBillStatisticsVO;
import com.yonyou.pmclouds.project.entity.ProjectBillVO;
import com.yonyou.pmclouds.project.mapper.ProjectBillMapper;
import com.yonyou.pmclouds.project.mapper.ProjectStatisticsMapper;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.UUID;
//计算推送数通用方法 实际就是往数据库中添加一条数据
public class UpdateBillCountForInsertProcessor<T extends SuperVO> implements SingleProcessor<T>, MultiProcessor<T> {
    //通过有参构造来执行这个方法
    private ProjectStatisticsMapper mapper;
    private ProjectBillMapper projectBillMapper;
    private String billType;

    private UpdateBillCountForInsertProcessor(ProjectStatisticsMapper mapper, ProjectBillMapper projectBillMapper, String billType) {
        this.mapper = mapper;
        this.projectBillMapper = projectBillMapper;
        this.billType = billType;
    }


    @Override
    public void process(T vo, T orig) throws BusinessException {
        //获取项目的ID
        String project = (String) BeanHelper.getProperty(vo, CommonFieldConst.PK_PROJECT);
        //如果没有获取到，则再次更换属性名获取
        if (StringUtils.isEmpty(project)) {
            project = (String) BeanHelper.getProperty(vo, CommonFieldConst.PKPROJECT);
        }
        //根据项目ID以及单据类型查询项目统计表（pm_project_statistics）中是否存在此项目的单据类型，如果为null，则向其表中添加一条此类型的数据
        if(mapper.selectStatistics(project,billType)==null){
            //获取租户ID，此写法不符合规范，改进：直接获取添加用户的所属租户信息
            String[] s = mapper.selectTenant(project);
            //创建一个项目统计对象，并为其字段赋值
            ProjectBillStatisticsVO pv = new ProjectBillStatisticsVO();
            pv.setPkProject(project);
            pv.setPkStatistics(UUID.randomUUID().toString());
            pv.setPkTenant(s[0]);
            pv.setBillCount(0);
            pv.setBillType(billType);
            pv.setChangeFlag(UUID.randomUUID().toString());
            pv.setDr((byte)0);
            //添加
            mapper.insert(pv);
        }
        //更改单据数量，此项目下的此类型下的单据数量加1
        mapper.increaseBillCount(1, project, billType);
        //===========把项目单据表转化到新表上面================
        genBillVOAndInsert(vo, project);
    }

    private void genBillVOAndInsert(T vo, String project) {
        //获取租户ID
        String tenant = (String) BeanHelper.getProperty(vo, CommonFieldConst.PKTENANT);
        //同样若那个属性名没获取到，换个属性名试试
        if (StringUtils.isEmpty(tenant)) {
            tenant = (String) BeanHelper.getProperty(vo, CommonFieldConst.PK_TENANT);
        }
        //获取创建时间
        Date creationTime = (Date) BeanHelper.getProperty(vo, CommonFieldConst.CREATIONTIME);
        //获取创建者
        String creator = (String) BeanHelper.getProperty(vo, CommonFieldConst.CREATOR);
        //获取单据状态
        Byte status = (Byte) BeanHelper.getProperty(vo, CommonFieldConst.BILLSTATUS);
        //若单据状态为空，则认为是驳回再提交后的状态
        if (status == null) {
            status = BillStatusConst.COMMON_COMMIT_STATUS;
        }
        // 增加计数
        ProjectBillVO billVO = new ProjectBillVO();
        billVO.setBillType(billType);
        billVO.setCreationtime(creationTime);
        billVO.setCreator(creator);
        billVO.setDr((byte) 0);
        billVO.setChangeFlag(UUID.randomUUID().toString());
        billVO.setPkBill((String) vo.pkFiledValue());
        billVO.setPkTenant(tenant);
        billVO.setPkProject(project);
        billVO.setBillStatus(status);
        //往项目单据表中添加单据，其作用是和项目单据统计表一样的，都是用来统计单据数量的，利用count(*)获取项目下的单据数量。
        //区别就是表的建立时间的先后，项目单据统计表没有单据状态字段，后来的需求中，需要根据单据状态来统计单据数量，所以导致了新表的诞生。
        projectBillMapper.insert(billVO);
    }

    //阅读顺序 第一
    @Override
    public void process(T[] vos, T[] origs) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) {
            return;
        }
        String project = (String) BeanHelper.getProperty(vos[0], CommonFieldConst.PK_PROJECT);
        if (StringUtils.isEmpty(project)) {
            project = (String) BeanHelper.getProperty(vos[0], CommonFieldConst.PKPROJECT);
        }
        mapper.increaseBillCount(vos.length, project, billType);
        for (T vo : vos) {
            genBillVOAndInsert(vo, project);
        }
    }

    @Component
    public static class UpdateBillCountForInsertProcessorFactory<T extends SuperVO> {
        @Autowired
        private ProjectStatisticsMapper mapper;
        @Autowired
        private ProjectBillMapper projectBillMapper;

        public UpdateBillCountForInsertProcessor<T> getProcessor(String billType) {
            return new UpdateBillCountForInsertProcessor<>(mapper, projectBillMapper, billType);
        }
    }
}
